package cn.wtg.kotlinlib.net.base

import android.content.Context
import cn.wtg.kotlinlib.net.base.SSL.initSSLSocketFactory
import cn.wtg.kotlinlib.net.base.SSL.initTrustManager
import okhttp3.OkHttpClient
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.CallAdapter
import retrofit2.adapter.rxjava3.RxJava3CallAdapterFactory
import okhttp3.Interceptor
import android.text.TextUtils
import android.util.Log
import cn.wtg.kotlinlib.net.base.ApiConfigConstant.CONNECT_TIMEOUT
import cn.wtg.kotlinlib.net.base.ApiConfigConstant.READ_TIMEOUT
import cn.wtg.kotlinlib.net.base.ApiConfigConstant.WRITE_TIMEOUT
import com.blankj.utilcode.util.ToastUtils
import okhttp3.logging.HttpLoggingInterceptor
import com.franmontiel.persistentcookiejar.PersistentCookieJar
import com.franmontiel.persistentcookiejar.cache.SetCookieCache
import com.franmontiel.persistentcookiejar.persistence.SharedPrefsCookiePersistor
import retrofit2.Converter
import retrofit2.Retrofit
import java.util.ArrayList
import java.util.concurrent.TimeUnit

/**
 * author: wtg
 * date:2020/3/13 0013
 * desc: Retrofit 管理类
 */
class RetrofitManager private constructor() {
    /**
     * 获取okhttpClient
     *
     * @return okhttpClient
     */
    var okHttpClient //
            : OkHttpClient? = null
        private set
    private var readTimeout: Int = READ_TIMEOUT
    private var readTimeoutTimeUnit = TimeUnit.SECONDS
    private var connectTimeout: Int = CONNECT_TIMEOUT
    private var connectTimeoutTimeUnit = TimeUnit.SECONDS
    private var writeTimeout: Int = WRITE_TIMEOUT
    private var writeTimeoutTimeUnit = TimeUnit.SECONDS
    private var converterFactory: Converter.Factory = GsonConverterFactory.create()
    private var callAdapterFactory: CallAdapter.Factory = RxJava3CallAdapterFactory.create()
    private val interceptors: MutableList<Interceptor> = ArrayList()

    /**
     * 获取域名
     *
     * @return 域名
     */
    var baseUrl: String? = null
        private set

    /**
     * 格式转换器
     *
     * @param converterFactory 格式转换器
     * @return RetrofitManager
     */
    fun setConverterFactory(converterFactory: Converter.Factory): RetrofitManager? {
        this.converterFactory = converterFactory
        return instance
    }

    /**
     * 适配器
     *
     * @param callAdapterFactory 适配器
     * @return RetrofitManager
     */
    fun setCallAdapterFactory(callAdapterFactory: CallAdapter.Factory): RetrofitManager? {
        this.callAdapterFactory = callAdapterFactory
        return instance
    }

    /**
     * 设置读取超时时间
     *
     * @param readTimeout 时间
     * @param timeUnit    单位
     * @return RetrofitManager
     */
    fun setReadTimeout(readTimeout: Int, timeUnit: TimeUnit): RetrofitManager? {
        this.readTimeout = readTimeout
        readTimeoutTimeUnit = timeUnit
        return instance
    }

    /**
     * 设置连接超时时间
     *
     * @param connectTimeout 时间
     * @param timeUnit       单位
     * @return RetrofitManager
     */
    fun setConnectTimeout(connectTimeout: Int, timeUnit: TimeUnit): RetrofitManager? {
        this.connectTimeout = connectTimeout
        connectTimeoutTimeUnit = timeUnit
        return instance
    }

    /**
     * 设置baseUrl
     *
     * @param baseUrl url
     */
    fun setBaseUrl(baseUrl: String?): RetrofitManager? {
        this.baseUrl = baseUrl
        ApiBaseUrl.URL_BASE = baseUrl!!
        return instance
    }

    /**
     * 设置写入超时时间
     *
     * @param writeTimeout 时间
     * @param timeUnit     单位
     * @return RetrofitManager
     */
    fun setWriteTimeout(writeTimeout: Int, timeUnit: TimeUnit): RetrofitManager? {
        this.writeTimeout = writeTimeout
        writeTimeoutTimeUnit = timeUnit
        return instance
    }

    /**
     * 添加拦截器
     *
     * @param interceptor 拦截器
     * @return RetrofitManager
     */
    fun addInterceptor(interceptor: Interceptor): RetrofitManager? {
        if (!interceptors.contains(interceptor)) {
            interceptors.add(interceptor)
        }
        return instance
    }

    /**
     * 初始化
     */
    fun init(context: Context?) {
        if (TextUtils.isEmpty(baseUrl)) {
            ToastUtils.showShort("请设置baseUrl")
            return
        }
        if (okHttpClient == null) {
            //添加拦截器
            val httpLoggingInterceptor =
                HttpLoggingInterceptor { message: String -> Log.e("okhttp4:", message) }
            httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY)
            val builder = OkHttpClient.Builder()
            builder.connectTimeout(
                connectTimeout.toLong(),
                connectTimeoutTimeUnit
            ) //                    .retryOnConnectionFailure(false)
                .readTimeout(readTimeout.toLong(), readTimeoutTimeUnit)
                .writeTimeout(writeTimeout.toLong(), writeTimeoutTimeUnit)
                .sslSocketFactory(initSSLSocketFactory(), initTrustManager())
                .addInterceptor(httpLoggingInterceptor) //添加下载拦截器
                .cookieJar(
                    PersistentCookieJar(
                        SetCookieCache(),
                        SharedPrefsCookiePersistor(context)
                    )
                )
            for (interceptor in interceptors) {
                builder.addInterceptor(interceptor)
            }
            okHttpClient = builder.build()
        }
        retrofit = okHttpClient?.let {
            baseUrl?.let { it1 ->
                Retrofit.Builder().client(it)
                    .addConverterFactory(converterFactory)
                    .addCallAdapterFactory(callAdapterFactory)
                    .baseUrl(it1)
                    .build()
            }
        }
    }

    /**
     * 设置okhttpClient
     *
     * @param okHttpClient 设置网络请求对象
     * @return 管理类
     */
    fun setOkHttpClient(okHttpClient: OkHttpClient?): RetrofitManager? {
        this.okHttpClient = okHttpClient
        return instance
    }

    /**
     * 创建service
     *
     * @param service service
     * @param <T>     类型
     * @return 服务类
    </T> */
    fun <T> createService(service: Class<T>?): T {
        return retrofit!!.create(service as Class<T>)
    }

    companion object {
        private var instance: RetrofitManager? = null
        private var retrofit: Retrofit? = null

        /**
         * 单例初始化数据
         *
         * @return instance
         */
        fun getInstance(): RetrofitManager? {
            if (instance == null) {
                synchronized(RetrofitManager::class.java) {
                    if (instance == null) {
                        instance = RetrofitManager()
                    }
                }
            }
            return instance
        }
    }
}